import importlib
import json
import logging

from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView, ListView
from django.conf import settings
from rest_framework.response import Response
from rest_framework.views import APIView

from common.custom_exceptions import UserException
from common.decorators import sns_userinfo
from common.tools.redis_tool import RedisStat
from common.tools.wechat_tools import getsign
from common.utils import QiniuUpload
from shop.models import ShopInfo

logger = logging.getLogger('qixiaobao')


class AuthTemplateView(TemplateView):

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseRedirect('login?next=/')
        self.shop = self.request.user.get_shop() or None
        return super(AuthTemplateView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        kwargs['user'] = self.request.user
        if kwargs.get('shop_id'):
            self.shop = get_obj(ShopInfo, id=kwargs.get('shop_id'), status=ShopInfo.STATUS_VALID)
        elif kwargs['user']:
            self.shop = self.request.user.get_shop() or None
        if hasattr(self, 'shop'):
            kwargs['shop'] = self.shop

        return super(AuthTemplateView, self).get_context_data(**kwargs)


class BaseListView(ListView):
    allow_empty = True
    paginate_by = 10

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return HttpResponseRedirect('login?next=/')
        if kwargs.get('shop_id'):
            self.shop = get_obj(ShopInfo, id=kwargs.get('shop_id'), status=ShopInfo.STATUS_VALID)
        elif kwargs['user']:
            self.shop = self.request.user.get_shop() or None
        return super(BaseListView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):

        if hasattr(self, 'shop'):
            kwargs['shop'] = self.shop
        context = super(BaseListView, self).get_context_data(**kwargs)
        context['count'] = len(self.object_list)
        if context['is_paginated']:
            # 判断显示的分页页码
            paginator = context['paginator']
            page_obj = context['page_obj']
            num_pages = paginator.num_pages
            current_page = page_obj.number
            if num_pages <= 6:
                return context
            if current_page + 4 >= num_pages:
                context['pages_number'] = range(num_pages - 5, num_pages + 1)
            elif current_page == 1:
                context['pages_number'] = [1, 2, 3, -1, num_pages - 2, num_pages - 1, num_pages]
            else:
                context['pages_number'] = [current_page - 1, current_page, current_page + 1, -1, num_pages - 2,
                                           num_pages - 1, num_pages]
        return context


class ImageUploadView(APIView):
    """上传图片"""

    # permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        # bucket = transforms_int(request.data.get('bucket', 'qixiaobao'))
        file = request.FILES.get('file', None)
        ret = QiniuUpload().upload_by_data(file)

        if not ret:
            return_info = {
                'code': 1,
                'msg': '上传失败!',
                'name': '',
                'data': None
            }
        else:
            return_info = {
                'code': 0,
                'msg': 'success',
                'name': ret.get('key'),
                'data': {
                    "src": settings.QINIU_DOMAIN + ret.get('key'),
                    "title": ret.get('key')
                }
            }
        return Response(return_info)


class AuthShopAPIView(APIView):

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return JsonResponse({'status': 2, 'detail': '未登录'})
        return super(AuthShopAPIView, self).dispatch(request, *args, **kwargs)


def get_obj(obj, **kwargs):
    try:
        return obj.objects.get(**kwargs)
    except obj.DoesNotExist:
        return None


def get_object_or_userexcept(obj, **kwargs):
    try:
        return obj.objects.get(**kwargs)
    except obj.DoesNotExist:
        raise UserException('{}不存在'.format(obj._meta.verbose_name))


class BaseTemplateView(TemplateView):
    def get_context_data(self, **kwargs):
        kwargs['user'] = self.request.user
        return super(BaseTemplateView, self).get_context_data(**kwargs)


class AuthMobileTemplateView(BaseTemplateView):

    @method_decorator(sns_userinfo)
    def dispatch(self, request, *args, **kwargs):
        try:
            self.shop = get_obj(ShopInfo, id=request.GET.get('shop', None), status=ShopInfo.STATUS_VALID)
        except ShopInfo.DoesNotExist:
            return render_to_response('mobile/message.html', {'message': '该店铺不存在'})
        return super(AuthMobileTemplateView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        kwargs['shop'] = self.shop
        if 'MicroMessenger' in self.request.META.get('HTTP_USER_AGENT', ''):
            if 'sign' not in kwargs:
                kwargs['sign'] = getsign(self.request, self.shop.id)
        return super(AuthMobileTemplateView, self).get_context_data(**kwargs)


def get_model_by_path_id(model_path, instance_id):
    module_path, class_name = model_path.rsplit('.', maxsplit=1)
    model_parent = importlib.import_module('%s.models' % module_path)
    model_class = getattr(model_parent, class_name)
    model_instance = get_obj(model_class, id=instance_id)
    return model_instance


class ModelFieldsEditView(AuthShopAPIView):
    def post(self, request, *args, **kwargs):
        if not {'model_path', 'instance_id', 'fields'}.issubset(request.data):
            logger.debug(request.data)
            return Response({'status': 1, 'detail': '参数不全'})

        model_instance = get_model_by_path_id(request.data.get('model_path'), request.data.get('instance_id'))
        # 增加权限检查
        if not model_instance:
            return Response({'status': 1, 'detail': '实例不存在！'})
        if not hasattr(model_instance, 'shop'):
            return Response({'status': 1, 'detail': '不支持的修改方式！'})
        if not request.user == model_instance.shop.user:
            return Response({'status': 1, 'detail': '无权限！'})
        field_list = json.loads(request.data.get('fields'))
        if field_list:
            for k, v in field_list.items():
                if not hasattr(model_instance, k):
                    continue
                setattr(model_instance, k, v)
            model_instance.save()
        else:
            return Response({'status': 1, 'detail': '修改字段列表为空'})
        return Response({'status': 0, 'detail': 'success'})
